﻿/*
COPYRIGHT (C) 2011-2013 Raynald Messié

THIS FILE IS PART OF SCRUMPILOT.

SCRUMPILOT IS FREE SOFTWARE: YOU CAN REDISTRIBUTE IT AND/OR MODIFY IT UNDER THE TERMS OF 
THE GNU LESSER GENERAL PUBLIC LICENSE VERSION v2.1 AS PUBLISHED BY THE FREE SOFTWARE FOUNDATION.

SCRUMPILOT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT WITHOUT ANY WARRANTY; WITHOUT
EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU LESSER
GENERAL PUBLIC LICENSE FOR MORE DETAILS.

YOU SHOULD HAVE RECEIVED A COPY OF THE GNU LESSER GENERAL PUBLIC LICENSE ALONG WITH SCRUMPILOT. 
IF NOT, SEE <HTTP://WWW.GNU.ORG/LICENSES/>.
*/

using System;
using System.Configuration;
using System.Diagnostics;
using System.Linq;
using System.ServiceModel;
using Elmah;
using Microsoft.TeamFoundation.VersionControl.Common;
using ScrumPilot.Domain;
using ScrumPilot.Domain.BPL;
using ScrumPilot.Helpers;
using ScrumPilot.TFSHelpers;

namespace ScrumPilot.web.tfsclient
{
    [ServiceBehavior(Namespace = "ScrumPilot.web.tfsclient")]
    public class WCFForTFS : IWCFForTFS
    {
        private TFSServices _tfs;
        private String _tfsRootUrl;

        void IWCFForTFS.Notify(string eventXml)
        {
            try
            {
                using (var unitOfWork = new UnitOfWork())
                {
                    tfsserverparam tfsparams = unitOfWork.TfsServerParamsRepository.GetOne();
                    this._tfsRootUrl = "http://" + tfsparams.tfsurl + ":" + tfsparams.tfsport + "/" + tfsparams.tfsdirectory + "/";

                    _tfs = new TFSServices(tfsparams.FormattedUrl, tfsparams.tfsuser, tfsparams.tfspassword);
                    _tfs.Authenticate();

                    var eventObject = _tfs.DeserializeChangedEvent<CheckinEvent>(eventXml);
                    if (eventObject != null)
                        AddCheckInEvent(eventObject, eventXml, unitOfWork);
                    else
                    {
                        var eventObject2 = _tfs.DeserializeChangedEvent<WorkItemChangedEvent>(eventXml);
                        if (eventObject2 != null)
                        {
                            AddWorkItemChangedEvent(eventObject2, eventXml, unitOfWork);

                            int id =
                                eventObject2.CoreFields.IntegerFields.FirstOrDefault(p => p.ReferenceName == "System.Id")
                                            .NewValue;
                            _tfs.CheckUserStoryState(id);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                ErrorSignal.FromCurrentContext().Raise(ex);
                EventLog.WriteEntry("ScrumPilot WS", ex.Message + " | " + ex.StackTrace, EventLogEntryType.Error);

            }
        }

        public void Test()
        {
            using (var unitOfWork = new UnitOfWork())
            {
                tfsserverparam tfsparams = unitOfWork.TfsServerParamsRepository.GetOne();
                this._tfsRootUrl = "http://" + tfsparams.tfsurl + ":" + tfsparams.tfsport + "/" + tfsparams.tfsdirectory + "/";
                _tfs = new TFSServices(tfsparams.FormattedUrl, tfsparams.tfsuser, tfsparams.tfspassword);
                _tfs.Authenticate();

                var spevent = unitOfWork.EventRepository.GetById(135787);
                this.PostYammerMessage(14, spevent.typeid, spevent.eventobject);
            }
            //throw new NotImplementedException();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="cevt"></param>
        /// <param name="eventXml"></param>
        /// <param name="db"> </param>
        private void AddCheckInEvent(CheckinEvent cevt, string eventXml, UnitOfWork db)
        {
            if (cevt != null && cevt.Artifacts.Count > 0)
            {
                var userId = (new UserServices(_tfs)).CheckIdentity(cevt.Committer, false);
                AddEvent(userId, 1, eventXml, db);
            }

        }

        private void AddWorkItemChangedEvent(WorkItemChangedEvent wevt, String eventXml, UnitOfWork db)
        {
            if (wevt != null)
            {
                var userId = (new UserServices(_tfs)).CheckIdentity(wevt.ChangerSid, false);
                AddEvent(userId, 2, eventXml, db);
            }
        }

        private void AddEvent(int usrId, int iType, string eventXml, UnitOfWork db)
        {
            if (usrId < 0) return;

            try
            {
                /*   db.EventRepository.Add(new spevent
                   {
                       createdate = DateTime.UtcNow,
                       typeid = iType,
                       userid = usrId,
                       eventobject = eventXml
                   });
                   db.Save();*/

                this.PostYammerMessage(usrId, iType, eventXml);
            }
            catch (Exception ex)
            {
                EventLog.WriteEntry("ScrumPilot WS", ex.Message + " | " + ex.StackTrace, EventLogEntryType.Error);
                throw;
            }
        }

        private void PostYammerMessage(int usrId, int iType, string eventXml)
        {
            var yammerSrv = new YammerServices(usrId);
            if (yammerSrv.IsProballyReadyToPost)
            {
                TFSWallContentObject wallContent = _tfs.GetWallContent(eventXml, iType, usrId, this._tfsRootUrl);
                if (wallContent != null)
                {

                    var message = String.Format("[{0} {1}] ", wallContent.WorkItemType, wallContent.ID) +
                                  wallContent.Descriptions + " " + wallContent.HourStatus;

                    if (!yammerSrv.IsImpersonated)
                    {
                        var user = (new UserServices(_tfs)).GetUser(usrId);
                        message = message.Insert(0, yammerSrv.IsImpersonated ? "" : user.Name + " => ");
                    }
                    yammerSrv.PostMessage(message, wallContent.ProjectName, wallContent.Iteration,
                        wallContent.Url, wallContent.Name);
                }
                else
                {
                    EventLog.WriteEntry("ScrumPilot WS", String.Format("WallContent Empty (type {0}, value : {1})", iType, eventXml), EventLogEntryType.Warning);
                }
            }
            else
            {
                EventLog.WriteEntry("ScrumPilot WS", "Yammer : not ready", EventLogEntryType.Warning);
            }
        }

        private tfsserverparam GetParamsFromConfig()
        {
            var tfsparams = new tfsserverparam
            {
                tfsurl = ConfigurationManager.AppSettings["tfsurl"],
                tfsport = ConfigurationManager.AppSettings["tfsport"],
                tfsdirectory = ConfigurationManager.AppSettings["tfsdirectory"],
                tfsuser = ConfigurationManager.AppSettings["tfsuser"],
                tfspassword = ConfigurationManager.AppSettings["tfspassword"]
            };
            return tfsparams;
        }
    }
}